#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define NONE_FFLUSH 0x0
#define LINE_FLLUSH 0x1
#define FULL_FFLUSH 0x2

#define NUM 1024

typedef struct MYFILE{

  int fd;
  int end;
  char str[NUM];
  int flags;  //刷新方式
}MYFILE;

MYFILE* myfopen(const char* filename,const char* method)
{
  assert(filename);
  assert(method);
  MYFILE* newfile = (MYFILE*)malloc(sizeof(MYFILE));
  if(strcmp(method,"w")==0)
  {
    newfile->fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666);  
  }

  else if(strcmp(method,"w+")==0)
  {
    newfile->fd = open(filename,O_RDONLY|O_CREAT|O_TRUNC|O_WRONLY,0666);  
  }
  else if(strcmp(method,"r")==0)
  {
    newfile->fd = open(filename,O_RDONLY);  
  }
  else if(strcmp(method,"r+")==0)
  {
    newfile->fd = open(filename,O_WRONLY|O_RDONLY|O_TRUNC);  
  }
  else if(strcmp(method,"a")==0)
  {
    newfile->fd = open(filename,O_WRONLY|O_CREAT|O_APPEND,0666);  
  }
  else if(strcmp(method,"a+")==0)
  {
    newfile->fd = open(filename,O_WRONLY|O_CREAT|O_APPEND|O_RDONLY,0666);  
  }
  else 
  {
    return NULL;
  }
  newfile->end = 0;
  newfile->flags = LINE_FLLUSH;
  memset(newfile->str,'\0',NUM);

  return newfile;
}



int myfread(char* str,int size,int n,MYFILE* fp)
{
  int len = read(fp->fd,fp->str+fp->end,n*size);
  if(len ==0)
    return 0;
  fp->end +=len/size;
  fp->end == NUM?NUM:fp->end+1;
  fp->str[fp->end-1] = '\0';
  switch(fp->flags)
  {
      case LINE_FLLUSH:
        if(fp->end>0&&fp->str[fp->end-2]=='\n')
        {
          strncpy(str,fp->str,fp->end);
          fp->end= 0;
        }
        else if(fp->end==NUM)
        { 
          strncpy(str,fp->str,fp->end);
          fp->end= 0;
        }
        break;
      case FULL_FFLUSH:
        if(fp->end==NUM)
        {
          strncpy(str,fp->str,fp->end);
          fp->end= 0;
        }
        break;
      case NONE_FFLUSH:
        //直接输出
        strncpy(str,fp->str,fp->end);
        fp->end = 0;
        break;

      default:
        exit(-1);//bug?
        break;
  }
  return len/size;
}


void myfwrite(const char* str,int size,int n,MYFILE* fp)
{
  strncpy(fp->str+fp->end,str,n);
  fp->end+=n;

  switch(fp->flags)
  {
      case LINE_FLLUSH:
        if(fp->end>0&&fp->str[fp->end-1]=='\n')
        {
          write(fp->fd,fp->str,fp->end);
          fp->end= 0;
          syncfs(fp->fd);
        }
        break;
      case FULL_FFLUSH:
        if(fp->end==NUM)
        {
          write(fp->fd,fp->str,strlen(fp->str));
          fp->end= 0;
          syncfs(fp->fd);
        }
        break;
      case NONE_FFLUSH:
        //直接输出
        write(fp->fd,fp->str,n); 
        fp->end = 0;
        syncfs(fp->fd);
        break;

      default:
        exit(-1);//bug?
        break;
  }
}

void myfflush(MYFILE* fp)
{
  assert(fp);
  if(fp->end>0)
  {
  write(fp->fd,fp->str,fp->end);
  fp->end = 0;
  syncfs(fp->fd);
  }
  //强制刷缓冲区
}


void myfclose(MYFILE* fp)
{
  assert(fp);
  myfflush(fp);
  close(fp->fd);
  free(fp);

}


int main()
{
  MYFILE* fp =  myfopen("test.txt","r");
  if(fp!=NULL)
  {
    printf("创建文件成功\n");
  }

  char readstr[NUM]= {0};
 // const char tmpstr[] = "-aaaaa";
 // myfwrite(tmpstr,sizeof(char),strlen(tmpstr),fp);
 // printf("写入了一个不满足条件的字符串\n");
 // fork();
 
  while(myfread(readstr,1,NUM,fp)!=0)
       printf("%s",readstr);
  myfclose(fp);
  return 0;
}
